/*
 * MIT License
 *
 * Copyright (c) 2023-present, tangli
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package tony.test.mybatis.datascope.unit

import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import tony.mybatis.datascope.IDataScopeProvider
import tony.mybatis.datascope.model.ScopedTable
import tony.mybatis.datascope.model.TableNameType
import tony.test.mybatis.datascope.DataScopeBaseTest
import tony.test.mybatis.datascope.model.DataScopeTestStub

/**
 * 数据权限提供者正确性测试
 * @author tangli
 * @date 2025/09/21 10:00
 */
@DisplayName("数据权限提供者正确性测试")
class DataScopeProviderTest : DataScopeBaseTest() {

    @Autowired
    private lateinit var dataScopeProvider: IDataScopeProvider


    @Nested
    @DisplayName("自定义提供者正确性验证")
    inner class CustomProviderTest {

        @Test
        @DisplayName("自定义表集合:配置正确性")
        fun testCustomTablesProviderCorrectness() {
            val customTables = setOf(
                ScopedTable("sys_dict", TableNameType.TABLE),
                ScopedTable("d", TableNameType.ALIAS),
                ScopedTable("sys_user", TableNameType.TABLE)
            )

            val customProvider = DataScopeTestStub.buildTestProvider(
                tables = customTables,
                userIdColumn = "custom_user_id",
                orgIdColumn = "custom_org_id"
            )

            logger.info("=== 自定义提供者测试 ===")
            logger.info("自定义表集合: {}", customProvider.tables)
            logger.info("自定义用户ID列名: {}", customProvider.userIdColumn)
            logger.info("自定义组织ID列名: {}", customProvider.orgIdColumn)

            assertEquals(3, customProvider.tables.size)
            assertEquals("custom_user_id", customProvider.userIdColumn)
            assertEquals("custom_org_id", customProvider.orgIdColumn)
            assertTrue(customProvider.tables.contains(ScopedTable("sys_dict", TableNameType.TABLE)))
            assertTrue(customProvider.tables.contains(ScopedTable("d", TableNameType.ALIAS)))
            logger.info("自定义提供者验证完成")
        }

        @Test
        @DisplayName("自定义提供者创建列:正确使用自定义默认值")
        fun testCustomProviderColumnCreationCorrectness() {
            val customProvider = DataScopeTestStub.buildTestProvider(
                userIdColumn = "my_default_user_id",
                orgIdColumn = "my_default_org_id"
            )

            val userColumn = customProvider.newUserIdColumn("specific_user_id")
            val orgColumn = customProvider.newOrgIdColumn("specific_org_id", "alias")

            logger.info("=== 自定义提供者列创建测试 ===")
            logger.info("用户列对象: {}", userColumn)
            logger.info("组织列对象: {}", orgColumn)

            // 验证用户列使用指定的用户ID列名和默认的组织ID列名
            assertEquals("specific_user_id", userColumn.userIdColumn)
            assertEquals("my_default_org_id", userColumn.orgIdColumn)

            // 验证组织列使用默认的用户ID列名和指定的组织ID列名
            assertEquals("my_default_user_id", orgColumn.userIdColumn)
            assertEquals("specific_org_id", orgColumn.orgIdColumn)
            assertEquals("alias", orgColumn.tableAlias)
            logger.info("自定义提供者列创建验证完成")
        }
    }

    @Nested
    @DisplayName("提供者集成正确性验证")
    inner class ProviderIntegrationTest {

        @Test
        @DisplayName("提供者与DataScope集成:配置传递正确性")
        fun testProviderDataScopeIntegrationCorrectness() {
            // 使用当前的提供者创建DataScope
            val dataScope = DataScopeTestStub.buildTestDataScope(
                userIdColumn = dataScopeProvider.userIdColumn,
                orgIdColumn = dataScopeProvider.orgIdColumn,
                tables = dataScopeProvider.tables.toSet()
            )

            val result = dataScope
                .userIdList(listOf("integration_user1"))
                .orgIdList(listOf("integration_org1"))
                .call {
                    logger.info("=== 提供者集成测试执行 ===")
                    "integration_test_result"
                }

            logger.info("=== 提供者DataScope集成测试 ===")
            logger.info("集成测试结果: {}", result)

            assertEquals("integration_test_result", result)
            logger.info("提供者DataScope集成验证完成")
        }
    }
}
